package pers.brozen.anka.utils.collections;

import org.apache.commons.collections4.CollectionUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.Function;

public class BatchUtils {

    private static final int BATCH_SIZE = 300;

    /**
     * 批量处理切分的时候，返回第index个List
     */
    public static <E> Collection<E> getBatchList(Integer index, int batchSize, Collection<E> collection) {
        List<E> list;
        if (collection instanceof List) {
            list = (List<E>) collection;
        } else {
            list = new ArrayList<>(collection);
        }

        if (index == list.size() / batchSize) {
            return list.subList(index * batchSize, list.size());
        } else {
            return list.subList(index * batchSize, (index + 1) * batchSize);
        }
    }

    /**
     * 批量处理
     */
    public static <E> int batch(int batchSize, Collection<E> list, Function<Collection<E>, Integer> handler) {
        try {
            return batchWithException(batchSize, list, handler);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return 0;
    }

    public static <E> int batchWithException(Integer batchSize, Collection<E> list, Function<Collection<E>, Integer> handler) {
        int back = 0;
        if (CollectionUtils.isNotEmpty(list)) {

            if (list.size() <= batchSize) {
                return handler.apply(list);
            }

            Collection<E> tmpList;
            for (int i = 0; i <= list.size() / batchSize; i++) {

                tmpList = BatchUtils.getBatchList(i, batchSize, list);

                if (CollectionUtils.isNotEmpty(tmpList)) {
                    int tmpBack = handler.apply(tmpList);
                    if (tmpBack == Integer.MIN_VALUE) {
                        break;
                    }
                    back += tmpBack;
                }
            }
        }
        return back;
    }


    /**
     * 批量处理
     */
    public static <E> int batch(Collection<E> list, Function<Collection<E>, Integer> handler) {
        return batch(BATCH_SIZE, list, handler);
    }

    /**
     * 批量处理
     */
    public static <E> int batchWithException(Collection<E> list, Function<Collection<E>, Integer> handler) {
        return batchWithException(BATCH_SIZE, list, handler);
    }

    public static <E, T> List<T> batch(List<E> list, Function<List<E>, List<T>> callbackHandler, int batchSize) {

        if (list.size() <= batchSize) {
            return callbackHandler.apply(list);
        }
        List<T> evalDetails = new ArrayList<>();

        List<E> subList;
        for (int i = 0; i <= list.size() / batchSize; i++) {
            subList = new ArrayList<>(BatchUtils.getBatchList(i, batchSize, list));
            if (CollectionUtils.isNotEmpty(subList)) {
                evalDetails.addAll(callbackHandler.apply(subList));
            }
        }
        return evalDetails;
    }
}
